﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Xml.Linq;
//using System.Text;
//using AspectSharp.Builder;
//using System.Xml;
//using System.IO;
//using AspectSharp;
//using System.Collections;
//using AspectSharp.Lang.AST;

//namespace Mbs.AOP
//{
//    public class AspectXmlEngineBuilder : IAspectEngineBuilder
//    {

//        private string AspectConfigFile; 

//        public AspectXmlEngineBuilder(string aspectConfigFile)
//        {
//            AspectConfigFile = aspectConfigFile;
//        }

//        public IAspectEngine Build()
//        {
//            if (!File.Exists(AspectConfigFile))
//                return null;

//            var builder = new CodeEngineBuilder();
//            var Configuration = new EngineConfiguration();

//            XElement root = XElement.Load(AspectConfigFile);
//            foreach (var item in root.Elements())
//            {
//                switch (item.Name.LocalName)
//                {
//                    case "import":
//                        LoadImport(Configuration, item);
//                        break;
//                    case "mixins":
//                        LoadMixins(Configuration, item);
//                        break;
//                    case "interceptors":
//                        LoadInterceptors(Configuration, item);
//                        break;
//                    case "aspect":
//                        LoadAspect(Configuration, item);
//                        break;
//                }
//            }

//            return builder.Build();
//        }

//        private void LoadAspect(EngineConfiguration Configuration, XElement node)
//        {
//            var items = (from item in node.Elements()
//                         let name = GetRequiredAttribute(item, "name")
//                         let singletypeNode = item.Element("for").Element("singletype")
//                         let type = GetRequiredAttribute(singletypeNode, "type")
//                         let refTypeEnum = EnumHelper.Parse<TargetTypeEnum>(GetRequiredAttribute(singletypeNode, "refTypeEnum"))
//                         let mixins = item.Elements("mixins")
//                         let pointCutNodes = items.Elements("pointcut")
//                         select new 
//                         {
//                             Name = name,
//                             SingleType = new TypeReference { Type = type, TargetType = refTypeEnum } ,
//                             Mixins = (from m in mixins
//                                        let mType = GetRequiredAttribute(m,"type")
//                                        let mRefTypeEnum = EnumHelper.Parse<TargetTypeEnum>(GetRequiredAttribute(m, "refTypeEnum"))
//                                        select new {
//                                            Type = mType,
//                                            TypeTarget = mRefTypeEnum
//                                        }).ToArray(),
//                             pointCuts = (from m in pointCutNodes
//                                       let mType = GetRequiredAttribute(m, "type")
//                                       let mRefTypeEnum = EnumHelper.Parse<TargetTypeEnum>(GetRequiredAttribute(m, "refTypeEnum"))
//                                       select new
//                                       {
//                                           Type = mType,
//                                           TypeTarget = mRefTypeEnum
//                                       }).ToArray(),
//                         }).ToArray();

//        }

//        private static void LoadInterceptors(EngineConfiguration Configuration, XElement node)
//        {
//            var items = (from item in node.Elements()
//                          let key = GetRequiredAttribute(item, "key")
//                          let type = GetRequiredAttribute(item, "type")
//                          let refTypeEnum = EnumHelper.Parse<TargetTypeEnum>(GetRequiredAttribute(item, "refTypeEnum"))
//                          select new InterceptorEntryDefinition
//                          {
//                              Key = key,
//                              TypeReference = new TypeReference
//                              {
//                                  LexicalInfo = LexicalInfo.Empty,
//                                  Type = type,
//                                  TargetType = refTypeEnum
//                              }
//                          }).ToArray();

//            if (items == null || items.Length < 1)
//                return;

//            foreach (var item in items)
//                Configuration.Interceptors.Add(item);
//        }

//        private static void LoadMixins(EngineConfiguration Configuration, XElement node)
//        {
//            var mixins = (from item in node.Elements()
//                          let key = GetRequiredAttribute(item, "key")
//                          let type = GetRequiredAttribute(item, "type")
//                          let refTypeEnum = EnumHelper.Parse<TargetTypeEnum>(GetRequiredAttribute(item, "refTypeEnum"))
//                          select new MixinEntryDefinition
//                          {
//                              Key = key,
//                              TypeReference = new TypeReference
//                              {
//                                  LexicalInfo = LexicalInfo.Empty,
//                                  Type = type,
//                                  TargetType = refTypeEnum
//                              }
//                          }).ToArray();

//            if (mixins == null || mixins.Length < 1)
//                return;

//            foreach (var item in mixins)
//                Configuration.Mixins.Add(item);
            
//        }

//        private static void LoadImport(EngineConfiguration Configuration, XElement item)
//        {
//            var import = new ImportDirective(LexicalInfo.Empty, GetRequiredAttribute(item, "namespace"));
//            import.AssemblyReference = CreateAssemblyReference(item);
//            Configuration.Imports.Add(import);
//        }


//        private static AssemblyReference CreateAssemblyReference(XElement node)
//        {
//            String assemblyName = GetAttribute(node, "assembly", null);

//            if (assemblyName != null)
//            {
//                return new AssemblyReference(LexicalInfo.Empty, assemblyName);
//            }

//            return null;
//        }
     
//        private static String GetRequiredAttribute(XElement node, String key)
//        {
//            String value = GetAttribute(node, key, null);
//            if (value == null)
//            {
//                throw new BuilderException("Error parsing contents. XmlNode " + node.Name + "requires an attribute named " + key);
//            }
//            return value;
//        }

//        private static String GetAttribute(XElement node, String key, String defaultValue)
//        {
//            XAttribute att = node.Attributes().FirstOrDefault(item=> string.Equals(item.Value , key, StringComparison.OrdinalIgnoreCase));
//            if (att == null)
//            {
//                return defaultValue;
//            }
//            return att.Value;
//        }
//    }
//}
